<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<meta http-equiv="X-UA-Compatible" content="ie=edge" />
		<title>表白爱心</title>
        <style>
            body {
                margin: 0;
                background-color: #000;
                color: rgb(215, 61, 133);
            }
            canvas {
                animation: run infinite 1s linear;
            }
            .text {
                position: absolute;
                z-index: 1;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
                font-size: 50px;
                opacity: 0.5;
                white-space: pre;
            }
            @keyframes run {
                /* 0% {
                    transform: scale(1);
                }
                50% {
                    transform: scale(1.2);
                }
                100% {
                    transform: scale(1);
                } */
            }
        </style>
	</head>

	<body>
        <div class="text">对象名字</div>
		<canvas id="myCanvas"></canvas>
		<script>
			function heart() {
				const cvs = document.getElementById('myCanvas')
				const { clientWidth: width, clientHeight: height } = document.documentElement
				const ctx = cvs.getContext('2d')
                cvs.width = width
                cvs.height = height
				let radian = 0
				let radian_add = Math.PI / 180
				ctx.translate(width / 2, height / 2)
                ctx.shadowBlur = 10
                ctx.lineJoin = 'round'
                ctx.shadowColor = 'rgb(215, 61, 133)'
                ctx.strokeStyle = 'rgb(215, 61, 133)'
                const points = []
				while (radian <= Math.PI * 2) {
					radian += radian_add
                    const x = getX(radian)
                    const y = getY(radian)
                    // ctx.lineTo(x, y)
                    points.push({
                        x,
                        y,
                        list: new Array(10).fill('').map(v => {
                            const fw = 100
                            const fx = x + Math.random() * fw - fw / 2
                            const fy = y + Math.random() * fw - fw / 2
                            return {
                                x: x,
                                y: y,
                                endX: fx,
                                endY: fy,
                                stepX: x > fx ? -1 : 1,
                                stepY: y > fy ? -1 : 1,
                                parentX: x,
                                parentY: y
                            }
                        })
                    })
				}
                // ctx.stroke()
                const render = () => {
                    ctx.beginPath()
                    ctx.clearRect(-width/2, -height/2, width, height)
                    ctx.lineWidth = 5
                    points.forEach(v => {
                        ctx.lineTo(v.x, v.y)
                    })
                    ctx.stroke()
                    ctx.beginPath()
                    ctx.lineWidth = 2
                    
                    points.forEach(v => {
                        v.list.forEach(k => {
                            ctx.moveTo(k.x, k.y)
                            ctx.lineTo(k.x + ctx.lineWidth, k.y + ctx.lineWidth)
                            k.x += k.stepX
                            k.y += k.stepY
                            if (k.stepX > 0) {
                                if (k.x > k.endX) {
                                    k.x = k.endX
                                }
                            } else {
                                if (k.x < k.endX) {
                                    k.x = k.endX
                                }
                            }
                            if (k.stepY > 0) {
                                if (k.y > k.endY) {
                                    k.y = k.endY
                                }
                            } else {
                                if (k.y < k.endY) {
                                    k.y = k.endY
                                }
                            }
                            if (k.x === k.endX && k.y === k.endY) {
                                k.x = k.parentX
                                k.y = k.parentY
                            }
                        })
                    })
                    ctx.stroke()
                    requestAnimationFrame(render)
                }
                render()
                
			}
			function getX(t) {
				return 15 * (12 * Math.sin(t) - 4 * Math.sin(3 * t))
			}
			function getY(t, bl = 1) {
				return (
					-15 *
					(13 * Math.cos(t) -
						5 * Math.cos(2 * t) -
						2 * Math.cos(3 * t) -
						Math.cos(4 * t))
				)
			}
			heart()
		</script>
	</body>
</html>
